package com.su.lightthings.fragment.device

import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import com.bumptech.glide.Glide
import com.jieli.jl_bt_ota.util.BluetoothUtil
import com.su.lightthings.R
import com.su.lightthings.adapter.AutoScanDeviceAdapter
import com.su.lightthings.adapter.ManuallyDeviceAdapter
import com.su.lightthings.base.BaseFragment
import com.su.lightthings.bluetooth.BtUtil
import com.su.lightthings.bluetooth.ProtocolDataUtil
import com.su.lightthings.databinding.FragmentAddDeviceBinding
import com.su.lightthings.mode.ScanDevice
import com.su.lightthings.mode.ScanResult
import com.su.lightthings.utils.ByteUtils
import com.su.lightthings.utils.Cons
import com.su.lightthings.view.LinearSpacingItemDecoration
import com.su.lightthings.viewmodel.BleViewModel
import com.su.lightthings.viewmodel.CommonViewModel
import com.su.lightthings.viewmodel.ConnectViewModel

class AddDeviceFragment : BaseFragment<FragmentAddDeviceBinding>() {

    private val TAG = "AddDeviceFragment"
    private val viewmodel = ConnectViewModel.INSTANCE
    private val mScanDeviceList = ArrayList<ScanDevice>(1)

    private val autoAdapter: AutoScanDeviceAdapter by lazy {
        AutoScanDeviceAdapter()
    }
    private val manuallyAdapter: ManuallyDeviceAdapter by lazy {
        ManuallyDeviceAdapter()
    }

    override fun getViewBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentAddDeviceBinding =
        FragmentAddDeviceBinding.inflate(layoutInflater)

    override fun initViews() {

        binding.rvAutoDevice.apply {
            adapter = autoAdapter
            layoutManager = GridLayoutManager(requireContext(), 3)
            addItemDecoration(LinearSpacingItemDecoration(10, 10, 10, 10))
        }
        binding.rvManually.apply {
            adapter = manuallyAdapter
            layoutManager = GridLayoutManager(requireContext(), 3)
            addItemDecoration(LinearSpacingItemDecoration(10, 10, 10, 10))
        }
        manuallyAdapter.submitList(Cons.ManualAddDeviceList.deviceList)

        //点击设备,进行连接
        autoAdapter.setOnItemClickListener { _, _, position ->
            val selected = autoAdapter.getItem(position)
            if (selected != null) {
                viewmodel.stopScan()
                viewmodel.connectBtDevice(selected.device)
//                findNavController().popBackStack()
            }
        }

        //测试方法
        manuallyAdapter.setOnItemClickListener { _, _, i ->
            Log.d(TAG, "is binder null: ${BleViewModel.INSTANCE.binder == null}")
            when (i) {
                0, 1, 2 -> BleViewModel.INSTANCE.write(BtUtil.makeWriteData(functionId = Cons.SettingFunctionId.STEP_TARGET))

                else -> BleViewModel.INSTANCE.write(
                    BtUtil.makeWriteData(
                        functionId = Cons.PushFunctionId.TIME_UPDATE, data = ProtocolDataUtil.updateTime(System.currentTimeMillis())
                    )
                )
            }
        }

        binding.ivBack.setOnClickListener {
            findNavController().popBackStack()
        }
    }

    override fun observer() {

        viewmodel.scanResultMLD.observe(viewLifecycleOwner) {
            Log.d(TAG, "scanResultMLD: ${it.state}  >>  ${it.device}")
            when (it.state) {
                ScanResult.SCAN_STATUS_IDLE -> {
                    Log.d(TAG, "observer: 查找结束")
                    Glide.with(requireContext()).load(R.drawable.auto_search_finish).into(binding.ivSearch)
                }

                ScanResult.SCAN_STATUS_SCANNING -> {
                    Log.d(TAG, "observer: 正在查找手表")
                    Glide.with(requireContext()).load(R.drawable.auto_search_loding).into(binding.ivSearch)
                    autoAdapter.apply {
                        this.submitList(mutableListOf())
//                        viewmodel.getConnectedDevice()?.let {
//                            addDevice(ScanDevice(it, 0))
//                        }
                    }
                }

                ScanResult.SCAN_STATUS_FOUND_DEV -> {
                    it.device.let {
                        if (it != null) {
                            var isContain = false
                            for (index in 0..<mScanDeviceList.size) {
                                Log.d(TAG, "扫描设备原始数据 index : $index")
                                var scanDevice: ScanDevice? = null
                                if (mScanDeviceList.isNotEmpty()) {
                                    scanDevice = mScanDeviceList[index]
                                }
                                Log.d(
                                    TAG, "扫描设备原始数据: ${scanDevice?.device?.name ?: ""}   >>  ${
                                        ByteUtils.toHexString(scanDevice!!.data)
                                    }"
                                )
                                if (BluetoothUtil.deviceEquals(it.device, scanDevice.device)) {
                                    mScanDeviceList[index] = it
                                    isContain = true
                                    break
                                }
                            }
                            //判断是不是我们的设备
                            val isTyDevice: Boolean = isTyDevice(
                                it.data ?: byteArrayOf(), 0x03, byteArrayOf(
                                    0xFF.toByte(), 0xE0.toByte(), 0xFE.toByte(), 0xE0.toByte()
                                )
                            )

                            val isPillow = isPillow(it.device.name)

                            if (!isContain && (isTyDevice || isPillow)) {
                                mScanDeviceList.add(it)
                            }
                        }
                    }
                    //发现设备
                    autoAdapter.submitList(mScanDeviceList.toList())
                }
            }
        }

        CommonViewModel.INSTANCE.btState.observe(viewLifecycleOwner) {
            if (it) {
                viewmodel.startScan()
            } else {
                viewmodel.stopScan()
                autoAdapter.submitList(mutableListOf())
            }
        }

        viewmodel.deviceConnectionMLD.observe(viewLifecycleOwner) { deviceConnection ->
            if (!isVisible) return@observe

            Log.d(TAG, "连接状态改变：${deviceConnection.device?.name}  >>  ${deviceConnection.state}")
            when (deviceConnection.state) {
            }
        }
    }

    private fun isTyDevice(
        originalByteArray: ByteArray,
        typeToFind: Byte,
        contentToFind: ByteArray,
    ): Boolean {
        Log.d(TAG, "isTyDevice: 数据长度： ${originalByteArray.size}")
        var index = 0
        while (index < originalByteArray.size) {
            // 检查是否有足够的字节来解析长度字段
            if (index + 1 >= originalByteArray.size) {
                Log.d(TAG, "isTyDevice: 数据不完整 1")
                return false // 数据不完整
            }
            val length = originalByteArray[index].toInt() and 0xFF // 获取长度，确保是正数
            // 检查长度字段所需的字节数是否足够
            if (index + length + 1 >= originalByteArray.size) {
                Log.d(TAG, "isTyDevice: 数据不完整 2")
                return false // 数据不完整
            }
            val type = originalByteArray[index + 1] // 获取类型
            // 检查是否与要查找的类型匹配
            if (type == typeToFind) {
                // 计算数据的结束位置
                val endIndex = index + length + 1
                // 检查长度是否大于0以及类型和内容是否匹配
                if (length > 0 && endIndex < originalByteArray.size && originalByteArray.sliceArray(index + 2 until endIndex) contentEquals contentToFind) {
                    Log.d(TAG, "isTyDevice: 匹配成功")
                    return true // 类型和内容匹配
                }
            }
            // 移动到下一个数据块的起始位置
            index += length + 1
        }
        Log.d(TAG, "isTyDevice: 匹配失败")
        return false // 未找到匹配的类型和内容
    }

    private fun isPillow(name: String): Boolean {
        return name == "BT16"
    }


    override fun onResume() {
        super.onResume()
        //进入页面,自动扫描
        Log.d(TAG, "onResume:进入页面,自动扫描 ")
        startScan()
    }

    private fun startScan() {
        mScanDeviceList.clear()
        viewmodel.startScan()
    }

    override fun onPause() {
        super.onPause()
        //退出页面,终止扫描
        Log.d(TAG, "onPause: 退出页面,终止扫描")
        viewmodel.stopScan()
    }
}